home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2003 November A / PCWK1103A.iso / ABBYY FineReader 7.0 PRO / data1.cab / pdf_draw.ps < prev    next >
Text File  |  2002-02-23  |  35KB  |  1,151 lines

  1. %    Copyright (C) 1994, 2000 Aladdin Enterprises.  All rights reserved.
  2. % This software is provided AS-IS with no warranty, either express or
  3. % implied.
  4. % This software is distributed under license and may not be copied,
  5. % modified or distributed except as expressly authorized under the terms
  6. % of the license contained in the file LICENSE in this distribution.
  7. % For more information about licensing, please refer to
  8. % http://www.ghostscript.com/licensing/. For information on
  9. % commercial licensing, go to http://www.artifex.com/licensing/ or
  10. % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. % San Rafael, CA  94903, U.S.A., +1(415)492-9861.
  12.  
  13. % $Id: pdf_draw.ps,v 1.36.2.1 2002/02/22 19:45:55 ray Exp $
  14. % pdf_draw.ps
  15. % PDF drawing operations (graphics, text, and images).
  16.  
  17. /.setlanguagelevel where { pop 2 .setlanguagelevel } if
  18. .currentglobal true .setglobal
  19. /pdfdict where { pop } { /pdfdict 100 dict def } ifelse
  20. GS_PDF_ProcSet begin
  21. pdfdict begin
  22.  
  23. % For simplicity, we use a single interpretation dictionary for all
  24. % PDF graphics operations, even though this is too liberal.
  25. /drawopdict 100 dict def
  26.  
  27. % ================================ Graphics ================================ %
  28.  
  29. % ---------------- Functions ---------------- %
  30.  
  31. % Note that resolvefunction converts a PDF Function to a PostScript Function;
  32. % resolve*fnproc converts a PDF function to a PostScript procedure.
  33.  
  34. /fnrdict mark
  35.   0 { .resolvefn0 }
  36.   2 { }
  37.   3 { .resolvefn3 }
  38.   4 { .resolvefn4 }
  39. .dicttomark readonly def
  40.  
  41. /.resolvefn0 {
  42.         % Don't lose our place in PDFfile.
  43.   PDFfile fileposition exch
  44.   dup true resolvestream
  45.         % The stream isn't positionable, so read all the data now.
  46.         % Stack: filepos fndict stream
  47.   1 index /Range oget length 2 idiv 2 index /BitsPerSample oget mul
  48.   2 index /Size oget { mul } forall
  49.   7 add 8 idiv string
  50.   1 index exch readstring pop exch closefile
  51.         % Stack: filepos fndict data
  52.   exch dup length 1 add dict .copydict
  53.   dup /DataSource 4 -1 roll put
  54.   exch PDFfile exch setfileposition
  55. } bdef
  56.  
  57. /.resolvefn3 {
  58.   dup length dict .copydict
  59.   dup /Bounds 2 copy knownoget { put } { pop pop } ifelse
  60.   dup /Encode 2 copy knownoget { put } { pop pop } ifelse
  61.   dup /Functions 2 copy oget mark exch dup {
  62.     oforce .resolvefn
  63.   } forall
  64.   counttomark -1 roll astore exch pop put
  65. } bdef
  66.  
  67. /.resolvefn4 {
  68.   PDFfile fileposition exch             % filepos fndict
  69.   dup true resolvestream                % filepos fndict stream
  70.   exch dup length dict copy             % filepos stream fndict2
  71.   dup /Function undef                   % filepos stream fndict2
  72.   exch dup token not {
  73.     () /rangecheck cvx signalerror
  74.   } if
  75.   exch token {
  76.     /rangecheck cvx signalerror
  77.   } if
  78.         % Use .bind to avoid idiom recognition.
  79.   .bind
  80.   1 index /Function 3 -1 roll put
  81.   exch PDFfile exch setfileposition
  82. } bdef
  83. currentdict /tfopdict undef
  84.  
  85. /.resolvefn {        % <fndict> .resolvefn <fndict'>
  86.   dup /FunctionType oget //fnrdict exch get exec
  87. } bdef
  88.  
  89. /resolvefunction {    % <fndict> resolvefunction <function>
  90.   .resolvefn
  91.   DEBUG { (%Function: ) print dup === flush } if
  92. } bdef
  93.  
  94. /resolvefnproc {    % <fndict> resolvefnproc <proc>
  95.   resolvefunction .buildfunction
  96. } bdef
  97.  
  98. /resolveidfnproc {    % <fndict> resolveidfnproc <proc>
  99.   dup /Identity eq { pop { } } { resolvefnproc } ifelse
  100. } bdef
  101.  
  102. /resolvedefaultfnproc {    % <fndict> <default> resolved'fnproc <proc>
  103.   1 index /Default eq { exch pop } { pop resolveidfnproc } ifelse
  104. } bdef
  105.  
  106. % ---------------- Shadings ---------------- %
  107.  
  108. /shrdict mark
  109.   /ColorSpace {
  110.     resolvecolorspace
  111.   }
  112.   /Function {
  113.     dup type /dicttype eq {
  114.       resolvefunction
  115.     } {
  116.       [ exch { oforce resolvefunction } forall ]
  117.     } ifelse
  118.   }
  119. .dicttomark readonly def
  120.  
  121. /resolveshading {    % <shadingstream> resolveshading <shading>
  122.   PDFfile fileposition exch
  123.   mark exch {
  124.     oforce //shrdict 2 index .knownget { exec } if
  125.   } forall .dicttomark
  126.   dup /ShadingType get 4 ge {
  127.     dup dup true resolvestream
  128.         % Make a reusable stream so that the shading doesn't
  129.         % reposition PDFfile at unexpected times.
  130.     /ReusableStreamDecode filter /DataSource exch put
  131.   } if exch PDFfile exch setfileposition
  132. } bdef
  133. /resolvesh {        % <shname> resolveshading <shading>
  134.   Page /Shading rget {
  135.     resolveshading
  136.   } {
  137.     null
  138.   }ifelse
  139. } bdef
  140.  
  141. % ---------------- Halftones ---------------- %
  142.  
  143. /spotfunctions mark
  144.   /Round {
  145.     abs exch abs 2 copy add 1 le {
  146.       dup mul exch dup mul add 1 exch sub 
  147.     } {
  148.       1 sub dup mul exch 1 sub dup mul add 1 sub
  149.     } ifelse
  150.   }
  151.   /Diamond {
  152.     abs exch abs 2 copy add .75 le {
  153.       dup mul exch dup mul add 1 exch sub
  154.     } {
  155.       2 copy add 1.23 le {
  156.     .85 mul add 1 exch sub
  157.       } {
  158.     1 sub dup mul exch 1 sub dup mul add 1 sub
  159.       } ifelse
  160.     } ifelse
  161.   }
  162.   /Ellipse {
  163.     abs exch abs 2 copy 3 mul exch 4 mul add 3 sub dup 0 lt {
  164.       pop dup mul exch .75 div dup mul add 4 div 1 exch sub
  165.     } {
  166.       dup 1 gt {
  167.     pop 1 exch sub dup mul exch 1 exch sub
  168.     .75 div dup mul add 4 div 1 sub
  169.       } {
  170.     .5 exch sub exch pop exch pop
  171.       } ifelse
  172.     } ifelse
  173.   }
  174.   /EllipseA { dup mul .9 mul exch dup mul add 1 exch sub }
  175.   /InvertedEllipseA { dup mul .9 mul exch dup mul add 1 sub }
  176.   /EllipseB { dup 5 mul 8 div mul exch dup mul exch add sqrt 1 exch sub }
  177.   /EllipseC { dup mul .9 mul exch dup mul add 1 exch sub }
  178.   /InvertedEllipseC { dup mul .9 mul exch dup mul add 1 sub }
  179.   /Line { exch pop abs neg }
  180.   /LineX { pop }
  181.   /LineY { exch pop }
  182.   /Square { abs exch abs 2 copy lt { exch } if pop neg }
  183.   /Cross { abs exch abs 2 copy gt { exch } if pop neg }
  184.   /Rhomboid { abs exch abs 0.9 mul add 2 div }
  185.   /DoubleDot { 2 {360 mul sin 2 div exch } repeat add }
  186.   /InvertedDoubleDot { 2 {360 mul sin 2 div exch } repeat add neg }
  187.   /SimpleDot { dup mul exch dup mul add 1 exch sub }
  188.   /InvertedSimpleDot { dup mul exch dup mul add 1 sub }
  189.   /CosineDot { 180 mul cos exch 180 mul cos add 2 div }
  190.   /Double { exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add }
  191.   /InvertedDouble {
  192.     exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add neg
  193.   }
  194. .dicttomark readonly def
  195.  
  196. /htrdict mark
  197.   1 { .resolveht1 }
  198.   5 { .resolveht5 }
  199.     % We don't support types 6, 10, or 16 yet.
  200. .dicttomark readonly def
  201.  
  202. /.resolveht1 {
  203.   mark exch {
  204.     oforce
  205.     1 index /SpotFunction eq {
  206.       dup type /nametype eq
  207.     { //spotfunctions exch get } { resolvefnproc }
  208.       ifelse
  209.     } {
  210.       1 index /TransferFunction eq {
  211.     resolveidfnproc
  212.       } if
  213.     } ifelse
  214.   } forall .dicttomark
  215. } bdef
  216.  
  217. /.resolveht5 {
  218.   mark exch {
  219.     oforce dup type /dicttype eq { resolvehalftone } if
  220.   } forall .dicttomark
  221. } bdef
  222.  
  223. /resolvehalftone {    % <dict> resolvehalftone <halftone>
  224.   dup /HalftoneType get //htrdict exch get exec
  225. } bdef
  226.  
  227. % ---------------- Graphics state management ---------------- %
  228.  
  229. /cmmatrix matrix def
  230. drawopdict begin
  231.             % Graphics state stack
  232.   /q { q } def
  233.   /Q { Q } def
  234.             % Graphics state setting
  235.   /cm { //cmmatrix astore concat } def
  236.   /i /setflat load def
  237.   /J /setlinecap load def
  238.   /d /setdash load def
  239.   /j /setlinejoin load def
  240.   /w /setlinewidth load def
  241.   /M /setmiterlimit load def
  242.   /gs { gs } def
  243. end
  244.  
  245. % Each entry in this dictionary is
  246. %    <gsres> <value> -proc- <gsres>
  247. /gsbg {
  248.   /BGDefault load resolvedefaultfnproc setblackgeneration
  249. } bdef
  250. /gsucr {
  251.   /UCRDefault load resolvedefaultfnproc setundercolorremoval
  252. } bdef
  253. /gstr {
  254.   dup type /arraytype eq {
  255.     { oforce /TRDefault load resolvedefaultfnproc } forall
  256.     setcolortransfer
  257.   } {
  258.     /TRDefault load resolvedefaultfnproc settransfer
  259.   } ifelse
  260. } bdef
  261. /gsparamdict mark
  262.   /SA { setstrokeadjust }
  263.   /OP { 1 index /op known not { dup op } if OP }
  264.     % The PDF 1.3 specification says that the name /Default is only
  265.     % recognized for {BG,UCR,TR}2.  However, PDF 1.3 files produced
  266.     % by Adobe Acrobat Distiller 4.0 for Windows use the name /Default
  267.     % with the older keys, so we have to implement this.
  268.   /BG { 1 index /BG2 known { pop } { gsbg } ifelse }
  269.   /UCR { 1 index /UCR2 known { pop } { gsucr } ifelse }
  270.   /TR { 1 index /TR2 known { pop } { gstr } ifelse }
  271.   /HT {
  272.     dup /Default eq {
  273.       pop .setdefaultscreen
  274.     } {
  275.     %****** DOESN'T IMPLEMENT THE STREAM CASE YET ******
  276.       resolvehalftone sethalftone
  277.     } ifelse
  278.   }
  279.   /HTP {
  280.     % HTP may be present even if this isn't a DPS interpreter.
  281.     /sethalftonephase where { pop aload pop sethalftonephase } { pop } ifelse
  282.   }
  283.     % PDF 1.3
  284.   /Font { aload pop Tf }
  285.   /LW { setlinewidth }
  286.   /LC { setlinecap }
  287.   /LJ { setlinejoin }
  288.   /ML { setmiterlimit }
  289.   /D { aload pop setdash }
  290.   /RI { ri }
  291.   /op { op }
  292.   /OPM { OPM }
  293.   /BG2 { gsbg }
  294.   /UCR2 { gsucr }
  295.   /TR2 { gstr }
  296.   /FL { setflat }
  297.   /SM {
  298.     % SM may be present even if this is only a Level 2 interpreter.
  299.     /setsmoothness where { pop setsmoothness } { pop } ifelse
  300.   }
  301.     % PDF 1.4
  302.     % All of these require the "transparency" feature in the interpreter.
  303.   /ca { ca }
  304.   /CA { CA }
  305.   /SMask { gssmask }
  306.   /AIS { AIS }
  307.   /BM { BM }
  308.   /TK { TK }
  309. .dicttomark readonly def
  310. /gs {            % <gsres> gs -
  311.   Page /ExtGState rget {
  312.     % We keep the dictionary on the stack during the forall so that
  313.     % keys that interact with each other have access to it.
  314.     dup {
  315.       oforce exch gsparamdict exch .knownget { exec } { pop } ifelse
  316.     } forall pop
  317.   } if
  318. } bdef
  319.  
  320. % ------ Transparency support ------ %
  321.  
  322. /gssmask {
  323.   dup /None eq {
  324.     pop null
  325.   } {
  326.     % Preprocess the SMask value into a parameter dictionary for
  327.     % .begintransparencymask, with added /BBox and /Draw keys.
  328.     mark exch        % Stack: mark smaskdict
  329.     dup /S oget /Subtype exch 3 2 roll
  330.             % Stack: mark ... smaskdict
  331.     dup /BC knownoget { /Background exch 3 2 roll } if
  332.     dup /TR knownoget {
  333.       resolveidfnproc /TransferFunction exch 3 2 roll
  334.     } if    
  335.     dup /G oget dup /BBox oget /BBox exch 4 2 roll
  336.     /.execmaskgroup cvx 2 packedarray cvx /Draw exch 3 2 roll
  337.     pop .dicttomark
  338.   } ifelse SMask
  339. } bdef
  340.  
  341. % This procedure is called to actually render the soft mask.
  342. /.execmaskgroup {    % <masknum> <paramdict> <formdict> .execmaskgroup -
  343.     % Save our place in PDFfile, and do a gsave to avoid resetting
  344.     % the color space.
  345.   gsave PDFfile fileposition 4 1 roll
  346.     % We have to select the group's color space so that the
  347.     % background color will be interpreted correctly.
  348.   dup /Group oget /CS knownoget { csresolve setcolorspace } if
  349.   exch dup /BBox get aload pop .begintransparencymask {
  350.     dup /Resources knownoget { oforce } { 0 dict } ifelse
  351.     exch false resolvestream
  352.     .execgroup .endtransparencymask
  353.   } .internalstopped {
  354.     .discardtransparencymask stop
  355.   } if
  356.   PDFfile exch setfileposition grestore
  357. } bdef
  358. % Paint a Form+Group XObject, either for a transparency mask or for a Do.
  359. /.execgroup {        % <resdict> <stream> .execgroup -
  360.   gsave
  361.   1 .setopacityalpha 1 .setshapealpha
  362.   0 .inittransparencymask 1 .inittransparencymask
  363.   /Compatible .setblendmode
  364.     % Execute the body of the Form, similar to DoForm.
  365.   pdfopdict .pdfruncontext
  366.   grestore
  367. } bdef
  368.  
  369. /.beginformgroup {    % groupdict bbox .beginformgroup -
  370.   exch mark exch            % bbox mark groupdict
  371.   dup /CS knownoget { csresolve setcolorspace } if
  372.   dup /I knownoget { /Isolated exch 3 2 roll } if
  373.   dup /K knownoget { /Knockout exch 3 2 roll } if
  374.   pop .dicttomark
  375.         % Stack: bbox paramdict
  376.   exch aload pop
  377.   .begintransparencygroup
  378. } bdef
  379.  
  380. % .paintgroupform implements the Form PaintProc in the case where the
  381. % Form XObject dictionary includes a Group key.  See .paintform below.
  382. /.paintgroupform {    % <resdict> <stream> <formdict> .paintgroupform -
  383.   dup /Group oget exch /BBox oget
  384.         % Stack: resdict stream groupdict bbox
  385.   .beginformgroup {
  386.     .execgroup
  387.   } .internalstopped {
  388.     .discardtransparencygroup stop
  389.   } if .endtransparencygroup
  390. } bdef
  391.  
  392. % Make an ImageType 103 (soft-masked) image.
  393. /makesoftmaskimage {    % <datasource> <imagemask> <SMask> makesoftmaskimage
  394.             %   <datasource> <imagemask>, updates currentdict =
  395.             %   imagedict
  396.         % See the ImageType 3 case of makemaskimage below.
  397.         % SMask is a stream, another Image XObject.
  398.         % Stack: datasource imagemask(false) smaskstreamdict
  399.   PDFfile fileposition exch
  400.   dup /Matte knownoget { /Matte exch def } if
  401.   dup length dict makeimagedict pop
  402.         % In order to prevent the two data sources from being
  403.         % aliased, we need to make at least one a reusable stream.
  404.         % We pick the mask, since it's smaller (in case we need to
  405.         % read all its data now).
  406.         % Stack: datasource imagemask(false) savedpos
  407.         % maskdict is currentdict
  408.   /DataSource DataSource mark
  409.     /Intent 1
  410.     /AsyncRead true
  411.   .dicttomark .reusablestreamdecode def
  412.   PDFfile exch setfileposition
  413.   currentdict end currentdict end
  414.   5 dict begin
  415.   /ImageType 103 def
  416.   /DataDict exch def
  417.   dup /InterleaveType 3 put
  418.   DataDict /Matte .knownget {
  419.     /Matte exch def
  420.   } if
  421.   AlphaIsShape { /ShapeMaskDict } { /OpacityMaskDict } ifelse exch def
  422.   /ColorSpace DataDict /ColorSpace get def
  423. } bdef
  424.  
  425. % ---------------- Color setting ---------------- %
  426.  
  427. /01_1 [0 1] readonly def
  428. /01_3 [0 1 0 1 0 1] readonly def
  429. /01_4 [0 1 0 1 0 1 0 1] readonly def
  430.  
  431. % The keys here are resolved (PostScript, not PDF) color space names.
  432. /csncompdict mark
  433.   /DeviceGray { pop 1 }
  434.   /DeviceRGB { pop 3 }
  435.   /DeviceCMYK { pop 4 }
  436.   /CIEBasedA { pop 1 }
  437.   /CIEBasedABC { pop 3 }
  438.   /ICCBased { 1 oget /N oget }
  439.   /Separation { pop 1 }
  440.   /DeviceN { 1 oget length }
  441. .dicttomark readonly def
  442.  
  443. % Perhaps some of the values in the following need to be modified
  444. % depending on the WhitePoint value....
  445. /cslabinit mark
  446.   /DecodeABC [{16 add 116 div} bind {500 div} bind {200 div} bind]
  447.   /MatrixABC [1 1 1 1 0 0 0 0 -1]
  448.   /DecodeLMN [
  449.     {dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse
  450.      0.9505 mul} bind
  451.     {dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse
  452.      } bind
  453.     {dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse
  454.      1.0890 mul} bind
  455.   ]
  456. .dicttomark readonly def
  457.  
  458. /csrdict mark
  459.   /DeviceGray {
  460.     /DefaultGray Page /ColorSpace rget { exch pop resolvecolorspace } if
  461.   }
  462.   /DeviceRGB {
  463.     /DefaultRGB Page /ColorSpace rget { exch pop resolvecolorspace } if
  464.   }
  465.   /DeviceCMYK { }
  466.   /CalGray {
  467.     1 oget 6 dict begin
  468.     dup /Gamma knownoget {
  469.       /exp load 2 packedarray cvx /DecodeA exch def
  470.     } if
  471.     dup /BlackPoint knownoget { /BlackPoint exch def } if
  472.     dup /WhitePoint knownoget { /WhitePoint exch def } if
  473.     pop [ /CIEBasedA currentdict end ]
  474.   }
  475.   /CalRGB {
  476.     1 oget 6 dict begin
  477.     dup /Gamma knownoget {
  478.       [ exch { /exp load 2 packedarray cvx } forall
  479.       ] /DecodeABC exch def
  480.     } if
  481.     dup /Matrix knownoget { /MatrixABC exch def } if
  482.     dup /BlackPoint knownoget { /BlackPoint exch def } if
  483.     dup /WhitePoint knownoget { /WhitePoint exch def } if
  484.     pop [ /CIEBasedABC currentdict end ]
  485.   }
  486.   /CalCMYK {
  487.     pop /DeviceCMYK        % not defined by Adobe
  488.   }
  489.   /Lab {
  490.     1 oget 6 dict begin
  491.     dup /Range knownoget not { [-100 100 -100 100] } if
  492.     [0 100 null null null null] dup 2 4 -1 roll putinterval
  493.     /RangeABC exch def
  494.     //cslabinit { def } forall
  495.     dup /BlackPoint knownoget { /BlackPoint exch def } if
  496.     dup /WhitePoint knownoget { /WhitePoint exch def } if
  497.     pop [ /CIEBasedABC currentdict end ]
  498.   }
  499.   /ICCBased {
  500.     PDFfile fileposition exch
  501.     dup dup 1 oget
  502.     mark exch { oforce } forall .dicttomark
  503.     dup dup true resolvestream
  504.     /ReusableStreamDecode filter /DataSource exch put
  505.     1 exch put
  506.     exch PDFfile exch setfileposition
  507.   } bind
  508.   /Separation {
  509.     aload pop exch oforce resolvecolorspace exch oforce resolvefnproc
  510.     4 array astore
  511.   }
  512.   /DeviceN {
  513.     0 4 getinterval                    % ignore attributes
  514.     aload pop 3 -1 roll oforce
  515.     3 -1 roll oforce resolvecolorspace
  516.     3 -1 roll oforce resolvefnproc
  517.     4 array astore
  518.   }
  519.   /Indexed {
  520.     aload pop 3 -1 roll oforce resolvecolorspace
  521.         % If the underlying space is a Lab space, we must scale
  522.         % the output of the lookup table as part of DecodeABC.
  523.     dup dup type /arraytype eq { 0 get } if /CIEBasedABC eq {
  524.       dup 1 get /DecodeLMN known {
  525.     1 get dup length dict copy
  526.     begin /DecodeABC [ 0 2 4 {
  527.       RangeABC 1 index 1 add get RangeABC 2 index get sub /mul load
  528.       RangeABC 3 index get /add load
  529.       DecodeABC 6 -1 roll 2 idiv get [ 6 1 roll aload pop ] cvx
  530.     } for ] def
  531.     /RangeABC //01_3 def
  532.     currentdict end /CIEBasedABC exch 2 array astore
  533.       } if
  534.     } if
  535.     3 1 roll
  536.     oforce dup type /stringtype ne {
  537.         % The color lookup table is a stream.
  538.         % Get its contents.  Don't lose our place in PDFfile.
  539.         % Stack: /Indexed basespace hival lookup
  540.     PDFfile fileposition 5 1 roll true resolvestream
  541.         % Stack: filepos /Indexed basespace hival lookupstream
  542.     1 index 1 add
  543.         % Stack: filepos /Indexed basespace hival lookupstream len
  544.     3 index
  545.       dup dup type /arraytype eq { 0 get } if
  546.       //csncompdict exch get exec mul
  547.     string readstring pop
  548.         % Stack: filepos /Indexed basespace hival table
  549.     5 -1 roll PDFfile exch setfileposition
  550.     }
  551.     if 4 array astore
  552.   }
  553.   /Pattern {
  554.     dup type /nametype ne {
  555.       dup length 1 gt {
  556.     1 oget resolvecolorspace
  557.     /Pattern exch 2 array astore
  558.       } if
  559.     } if
  560.   }
  561. .dicttomark readonly def
  562.  
  563. /cssubst {        % <csname> cssubst <cspace'> true
  564.             % <csname> cssubst false
  565.   dup resolvecolorspace
  566.   dup 1 index ne { exch pop true } { pop pop false } ifelse
  567. } bdef
  568.  
  569. /csnames mark
  570.   /DeviceGray dup  /DeviceRGB dup  /DeviceCMYK dup  /Pattern dup
  571. .dicttomark readonly def
  572. /csresolve {        % <csresourcename> csresolve <cspace>
  573.   dup Page /ColorSpace rget {
  574.     exch pop resolvecolorspace
  575.   } {
  576.     //csnames 1 index known not { /undefined cvx signalerror } if
  577.   } ifelse
  578. } bdef
  579. /resolvecolorspace {    % <cspace> resolvecolorspace <cspace'>
  580.   dup dup type /arraytype eq { 0 get } if
  581.   //csrdict exch .knownget {
  582.     exec dup type /nametype ne { dup length 1 eq { 0 get } if } if
  583.   } {
  584.     csresolve
  585.   } ifelse
  586. } bdef
  587.  
  588. /scresolve {    % <c0> ... scresolve <multi>
  589.         % We can't really make sc[n] and SC[N] work, because
  590.         % the color space information isn't available at
  591.         % conversion time; so we hack it by assuming that
  592.         % all the operands on the stack are used, and that
  593.         % if the top operand is a name, it's a Pattern resource.
  594.   dup type /nametype eq
  595.     { Page /Pattern rget { resolvepattern } { null } ifelse }
  596.   if
  597.   dup type /dicttype eq {
  598.         % Check the PaintType, if any (shading patterns don't
  599.         % have one).
  600.     dup /PaintType .knownget { 2 eq } { false } ifelse
  601.   } {
  602.     .pdfcount 1 gt
  603.   } ifelse
  604. } bdef
  605.  
  606. /.pdfpaintproc {         % <patdict> <resdict> .pdfpaintproc -
  607.   DEBUG { (%Begin PaintProc) = flush } if
  608.     % For uncolored patterns, we have to unbind the current
  609.     % color and color space before running the PaintProc.
  610.     % There's no harm in doing this for colored patterns,
  611.     % so for simplicity, we always do it.
  612.   PDFfile fileposition 3 1 roll
  613.   q
  614.   null sc1 null SC1
  615.   exch false resolvestream pdfopdict .pdfruncontext
  616.   Q
  617.   DEBUG { (%End PaintProc) = flush } if
  618.   PDFfile exch setfileposition
  619. } bdef
  620.  
  621. /resolvepattern {    % <patternstreamdict> resolvepattern <patterndict>
  622.         % Don't do the resolvestream now: just capture the data
  623.         % from the file if necessary.
  624.   dup length dict copy
  625.   dup /FilePosition .knownget {
  626.     1 index /File get dup fileposition 3 1 roll
  627.         % Stack: dict savepos pos file
  628.     dup 3 -1 roll setfileposition
  629.     dup 3 index /Length oget string readstring pop
  630.         % Stack: dict savepos file string
  631.     3 1 roll exch setfileposition
  632.     1 index /File 3 -1 roll put
  633.     dup /FilePosition undef
  634.   } if
  635.   dup /Shading knownoget {
  636.     resolveshading 1 index /Shading 3 -1 roll put
  637.   } if
  638.   dup /PaintProc [
  639.         % Bind the resource dictionary into the PaintProc.
  640.     2 index /Resources knownoget { oforce } { 0 dict } ifelse
  641.     /.pdfpaintproc cvx
  642.   ] cvx put
  643.   DEBUG {
  644.     (%Pattern: ) print dup === flush
  645.   } if
  646. } bdef
  647.  
  648. drawopdict begin
  649.   /g { /DeviceGray cssubst { cs sc1 } { g } ifelse } bdef
  650.   /rg { /DeviceRGB cssubst { cs sc* } { rg } ifelse } bdef
  651.   /k { k } bdef
  652.   /cs { csresolve cs } bdef
  653.   /sc { scresolve { sc* } { sc1 } ifelse } bdef
  654.   /scn /sc load def
  655.   /G { /DeviceGray cssubst { CS SC1 } { G } ifelse } bdef
  656.   /RG { /DeviceRGB cssubst { CS SC* } { RG } ifelse } bdef
  657.   /K { K } bdef
  658.   /CS { csresolve CS } bdef
  659.   /ri { ri } bdef
  660.   /SC { scresolve { SC* } { SC1 } ifelse } bdef
  661.   /SCN /SC load def
  662. end
  663.  
  664. % ---------------- Paths ---------------- %
  665.  
  666. drawopdict begin
  667.             % Path construction
  668.   /m /moveto load def
  669.   /l /lineto load def
  670.   /c /curveto load def
  671.   /v { currentpoint 6 2 roll curveto } def
  672.   /y { 2 copy curveto } def
  673.   /re {
  674.    4 2 roll moveto  exch dup 0 rlineto  0 3 -1 roll rlineto  neg 0 rlineto
  675.    closepath
  676.   } def
  677.   /h /closepath load def
  678.             % Path painting and clipping
  679.   /n { n } def
  680.   /S { S } def
  681.   /s { s } def
  682.   /f { f } def
  683.   /f* { f* } def
  684.   /B { B } def
  685.   /b { b } def
  686.   /B* { B* } def
  687.   /b* { b* } def
  688.   /W { W } def
  689.   /W* { W* } def
  690.   /sh { resolvesh shfill } def
  691. end
  692.  
  693. % ---------------- XObjects ---------------- %
  694.  
  695. /xobjectprocs mark        % <dict> -proc- -
  696.   /Image { DoImage }
  697.   /Form { DoForm }
  698.   /PS { DoPS }
  699. .dicttomark readonly def
  700.  
  701. % Note that the keys in defaultdecodedict are resolved (PostScript, not PDF)
  702. % color space names.
  703. /defaultdecodedict mark
  704.   /DeviceGray { pop //01_1 } bind
  705.   /DeviceRGB { pop //01_3 } bind
  706.   /DeviceCMYK { pop //01_4 } bind
  707.   /CIEBasedA { 1 get /RangeA .knownget not { //01_1 } if } bind
  708.   /CIEBasedABC { 1 get /RangeABC .knownget not { //01_3 } if } bind
  709.   /ICCBased {
  710.      1 oget dup /Range .knownget {
  711.        exch pop
  712.      }{
  713.        /N get [ exch {0 1} repeat ] readonly
  714.      } ifelse
  715.   } bind
  716.   /Separation { pop //01_1 } bind
  717.   /DeviceN {
  718.     1 oget length [ exch {0 1} repeat ] readonly
  719.   } bind
  720.   /Indexed {
  721.     pop [ 0 1 BitsPerComponent bitshift 1 sub ]
  722.   } bind
  723. .dicttomark readonly def
  724.  
  725. /checkaltimage {    % <resdict> checkaltimage <resdict[']>
  726.   Printed {
  727.     dup /Alternates knownoget {
  728.       {
  729.     dup /DefaultForPrinting knownoget {
  730.       {
  731.         /Image oget exch pop exit
  732.       } {
  733.         pop
  734.       } ifelse
  735.     } {
  736.       pop
  737.     } ifelse
  738.       } forall
  739.     } if
  740.   } if
  741. } bdef
  742.  
  743. /makeimagedict {    % <resdict> <newdict> makeimagedict <imagemask>
  744.             % On return, newdict' is currentdict
  745.   begin
  746.   /Width 2 copy oget def
  747.   /Height 2 copy oget def
  748.   /BitsPerComponent 2 copy oget def
  749.   /Interpolate 2 copy knownoget { def } { pop } ifelse
  750.   makeimagekeys
  751. } bdef
  752. /makeimagekeys {    % <resdict> makeimagekeys <imagemask>
  753.         % newdict is currentdict
  754.         % Assumes Width, Height, BPC, Interpolate already copied.
  755.   /ImageType 1 def
  756.   /ImageMatrix Width 0 0
  757.         % Handle 0-height images specially.
  758.     Height dup 0 eq { pop 1 } if neg 0 1 index neg
  759.     6 array astore def
  760.   dup /ImageMask knownoget dup { and } if {
  761.         % Image mask
  762.         % Decode is required for the PostScript image operators.
  763.                 % AI8 writes bogus decode array [0 1 0 0 0 0 0 0]
  764.     /Decode 2 copy knownoget { 0 2 getinterval } { //01_1 } ifelse def
  765.         % BitsPerComponent may be missing for masks.
  766.         % The spec requires it, but some producers omit it, and
  767.         % Acrobat Reader doesn't care.
  768.     /BitsPerComponent 2 copy known { pop } { 1 def } ifelse
  769.     true
  770.   } {
  771.         % Opaque image
  772.     dup /ColorSpace oget resolvecolorspace /ColorSpace exch def
  773.         % Decode is required for the PostScript image operators.
  774.     /Decode 2 copy knownoget not {
  775.       ColorSpace //defaultdecodedict
  776.       ColorSpace dup type /arraytype eq { 0 get } if get exec
  777.     } if def
  778.     false
  779.   } ifelse
  780.         % Even though we're going to read data,
  781.         % pass false to resolvestream so that
  782.         % it doesn't try to use Length (which may not be present).
  783.   exch false resolvestream /DataSource exch def
  784. } bdef
  785.  
  786. /DoImage {
  787.   checkaltimage dup length 6 add dict
  788.   1 index /SMask knownoget { 1 index exch /SMask exch put } if
  789.   1 index /Mask knownoget { 1 index exch /Mask exch put } if
  790.   makeimagedict doimage
  791. } bdef
  792. /makemaskimage {    % <datasource> <imagemask> <Mask> makemaskimage
  793.             %   <datasource> <imagemask>, updates currentdict =
  794.             %   imagedict
  795.   dup type /arraytype eq {
  796.     /ImageType 4 def
  797.     /MaskColor exch def
  798.   } {
  799.         % Mask is a stream, another Image XObject.
  800.         % Stack: datasource imagemask(false) maskstreamdict
  801.     PDFfile fileposition exch
  802.     dup length dict makeimagedict pop
  803.         % In order to prevent the two data sources from being
  804.         % aliased, we need to make at least one a reusable stream.
  805.         % We pick the mask, since it's smaller (in case we need to
  806.         % read all its data now).
  807.         % Stack: datasource imagemask(false) savedpos
  808.         % maskdict is currentdict
  809.     /DataSource DataSource mark
  810.       /Intent 1
  811.       /AsyncRead true
  812.     .dicttomark .reusablestreamdecode def
  813.     PDFfile exch setfileposition
  814.     currentdict end currentdict end
  815.     5 dict begin
  816.     /ImageType 3 def
  817.     /InterleaveType 3 def
  818.     /DataDict exch def
  819.     /MaskDict exch def
  820.     /ColorSpace DataDict /ColorSpace get def
  821.   } ifelse
  822. } bdef
  823. /doimage {    % <imagemask> doimage -
  824.         % imagedict is currentdict, gets popped from dstack
  825.   DataSource exch
  826.   PDFversion 1.4 ge { currentdict /SMask knownoget } { false } ifelse {
  827.     makesoftmaskimage
  828.   } {
  829.     currentdict /Mask knownoget {
  830.       makemaskimage
  831.     } if
  832.   } ifelse
  833.         % Stack: datasource imagemask
  834.    % image and imagemask can be redefined in gs_init.ps to tweak interpolation
  835.    % after device-specific files are run. Don't bind them here.
  836.    { currentdict end setfillstate /imagemask }
  837.    { ColorSpace setcolorspace currentdict end setfillblend /image }
  838.   ifelse
  839.   .systemvar exec
  840.    
  841.         % Close the input stream, unless it is PDFfile or
  842.         % PDFsource.
  843.   dup dup PDFfile eq exch PDFsource eq or { pop } { closefile } ifelse
  844. } bdef
  845.  
  846. /.paintform {    % <formdict> <resdict> <stream> .paintform -
  847.   3 -1 roll dup /Group known {
  848.     .paintgroupform
  849.   } {
  850.     pop pdfopdict .pdfruncontext
  851.   } ifelse
  852. } bdef
  853.  
  854. /DoForm {
  855.     % Adobe 2nd edition of the PDF 1.3 spec makes /FormType
  856.     % and /Matrix keys optional. Cope with the missing keys.
  857.   dup length
  858.   1 index /Matrix known
  859.     { dict
  860.     }
  861.     { 1 add dict
  862.       dup /Matrix { 1 0 0 1 0 0 } cvlit put
  863.     }
  864.   ifelse
  865.   copy
  866.   dup /FormType known not {
  867.     dup length 1 add dict copy dup /FormType 1 put
  868.   } if
  869.  
  870.   dup [ 2 index /Resources knownoget { oforce } { 0 dict } ifelse
  871.   3 index false /resolvestream cvx
  872.   /.paintform cvx
  873.   ] cvx /PaintProc exch put
  874.   execform
  875. } bdef
  876.  
  877. /DoPS {
  878.   true resolvestream cvx exec
  879. } bdef
  880.  
  881. drawopdict begin
  882.   /Do {
  883.     setfillblend
  884.     PDFfile fileposition exch
  885.     dup Page /XObject rget { 
  886.       exch pop dup /Subtype get xobjectprocs exch get
  887.         % Don't leave extra objects on the stack while executing
  888.         % the definition of the form.
  889.       3 -1 roll 2 .execn
  890.     } {
  891.         % This should cause an error, but Acrobat Reader can
  892.         % continue, so we do too.
  893.       (%stderr) (w) file
  894.       dup (****************Undefined XObject resource: ) writestring 
  895.       dup 3 -1 roll write===
  896.       flushfile
  897.     } ifelse
  898.     PDFfile exch setfileposition
  899.   } bdef
  900. end
  901.  
  902. % ---------------- In-line images ---------------- %
  903.  
  904. % Undo the abbreviations in an in-line image dictionary.
  905. % Note that we must look inside array values.
  906. % /I is context-dependent.
  907. /unabbrevkeydict mark
  908.   /BPC /BitsPerComponent  /CS /ColorSpace  /D /Decode  /DP /DecodeParms
  909.   /F /Filter  /H /Height  /I /Interpolate  /IM /ImageMask  /W /Width
  910. .dicttomark readonly def
  911. /unabbrevvaluedict mark
  912.   /AHx /ASCIIHexDecode  /A85 /ASCII85Decode  /CC /CalCMYK
  913.   /CCF /CCITTFaxDecode  /CG /CalGray  /CR /CalRGB
  914.   /DCT /DCTDecode  /CMYK /DeviceCMYK  /Fl /FlateDecode
  915.   /G /DeviceGray  /RGB /DeviceRGB
  916.   /I /Indexed  /LZW /LZWDecode  /RL /RunLengthDecode
  917. .dicttomark readonly def
  918. /unabbrevtypedict mark
  919.   /nametype {
  920.     //unabbrevvaluedict 1 index .knownget { exch pop } if
  921.   }
  922.   /arraytype {
  923.     dup 0 1 2 index length 1 sub {
  924.       2 copy get unabbrevvalue put dup
  925.     } for pop
  926.   }
  927. .dicttomark readonly def
  928. /unabbrevvalue {    % <obj> unabbrevvalue <obj'>
  929.   oforce //unabbrevtypedict 1 index type .knownget { exec } if
  930. } bdef
  931.  
  932. drawopdict begin
  933.   /BI { mark } bdef
  934.   /ID {
  935.     counttomark 2 idiv dup 6 add dict begin {
  936.       exch //unabbrevkeydict 1 index .knownget { exch pop } if
  937.       exch unabbrevvalue def
  938.     } repeat pop
  939.     /File PDFsource def
  940.     currentdict makeimagekeys doimage    
  941.     % The Adobe documentation says that the data following ID
  942.     % consists of "lines", and some PDF files (specifically, some files
  943.     % produced by PCL2PDF from Visual Software) contain garbage bytes
  944.     % between the last byte of valid data and an EOL.
  945.         % Some files (PDFOUT v3.8d by GenText) have EI immediately following
  946.         % the stream. Some have no EOL and garbage bytes.
  947.         % Therefore, we skip all bytes before EI or EOL 
  948.     0
  949.       { PDFsource read not { //true exit } if
  950.         dup 10 eq 1 index 13 eq or
  951.           { pop PDFsource token pop /EI ne exit
  952.           }
  953.         if
  954.         exch 69 eq 1 index 73 eq and { //false exit } if  % 'EI'
  955.       }
  956.     loop
  957.     exch pop
  958.       { /ID cvx /syntaxerror signalerror
  959.       }
  960.     if
  961.   } bdef
  962. end
  963.  
  964. % ================================ Text ================================ %
  965.  
  966. drawopdict begin
  967.             % Text control
  968.   /BT { BT } def
  969.   /ET { ET } def
  970.   /Tc { Tc } def
  971.   /TL { TL } def
  972.   /Tr { Tr } def
  973.   /Ts { Ts } def
  974.   /Tw { Tw } def
  975.   /Tz { Tz } def
  976.             % Text positioning
  977.   /Td { Td } def
  978.   /TD { TD } def
  979.   /Tm { Tm } def
  980.   /T* { T* } def
  981.             % Text painting
  982.   /Tj { Tj } def
  983.   /' { ' } def
  984.   /" { " } def
  985.   /TJ { TJ } def
  986. end
  987.  
  988. % ============================== Annotations ============================== %
  989.  
  990.  
  991.  
  992. % Get and normalize an annotation's rectangle.
  993. /annotrect {        % <annot> annotrect <x> <y> <w> <h>
  994.   /Rect get aload pop
  995.   exch 3 index sub dup 0 lt { dup 5 -1 roll add 4 1 roll neg } if
  996.   exch 2 index sub dup 0 lt { dup 4 -1 roll add 3 1 roll neg } if
  997. } bdef
  998.  
  999. % Set an annotation color.
  1000. /annotsetcolor {    % <annot> annotsetcolor -
  1001.   /C knownoget { aload pop setrgbcolor } { 0 setgray } ifelse
  1002. } bdef
  1003.  
  1004. % Draw the border.  Currently, we ignore requests for beveling, and we
  1005. % don't round the corners of rectangles.
  1006. /strokeborder {        % <annot> <width> <dash> strokeborder -
  1007.   1 index 0 ne {    % do not draw if border width is 0
  1008.     gsave
  1009.     2 index annotsetcolor
  1010.     0 setdash dup setlinewidth
  1011.     exch annotrect
  1012.     2 { 4 index sub 4 1 roll } repeat
  1013.     2 { 4 index 0.5 mul add 4 1 roll } repeat
  1014.     rectstroke pop
  1015.     grestore
  1016.   } {
  1017.     pop pop pop
  1018.   } ifelse
  1019. } bdef
  1020.  
  1021. % Draw an annotation border.
  1022. /drawborder {        % <annot> drawborder -
  1023.   gsave
  1024.   dup /BS knownoget {
  1025.     dup /W knownoget not { 1 } if
  1026.     [] 2 index /S knownoget {
  1027.       /D eq { 2 index /D knownoget not { [3] } if exch pop } if
  1028.     } if 3 -1 roll pop strokeborder
  1029.   } {
  1030.     dup /Border knownoget {
  1031.       dup 2 get
  1032.       exch dup length 3 gt { 3 get } { pop [] } ifelse
  1033.       strokeborder
  1034.     } {
  1035.       pop
  1036.     } ifelse
  1037.   } ifelse
  1038.   grestore
  1039. } bdef
  1040.  
  1041. %
  1042. %   The PDF annotation F (flags) integer is bit encoded.
  1043. %   Bit 1 (LSB) Invisible:  1 --> Do not display if no handler.
  1044. %         Note:  We have no handlers but we ignore this bit.
  1045. %   Bit 2 Hidden:  1 --> Do not display.  We will not display if this bit is set.
  1046. %   Bit 3 Print:  1 --> Display if printing.  We will display if this bit set
  1047. %         (and not hidden) and Printed is true
  1048. %   Bit 4 NoZoom:  1 --> Do not zoom annotation even if image is zoomed.
  1049. %   Bit 5 NoRotate:  1 --> Do not rotate annotation even if image is rotated.
  1050. %   Bit 6 NoView:  0 --> Display if this is a 'viewer'.  We will display
  1051. %         if this bit is not set (and not hidden) and Printed is false
  1052. %   Bit 7 Read Only - 1 --> No interaction.  We ignore this bit
  1053. %
  1054. /annotvisible {            % <annot> annotvisible <visible>
  1055.   /F knownoget not { 0 } if         % Get flag value
  1056.   dup 2 and 0 eq              % Check hidden flag
  1057.   exch dup 4 and 0 ne Printed and    % Check print flag
  1058.   exch 64 and 0 eq Printed not and    % Check noview flag
  1059.   or                    % Combine print and view
  1060.   and                     % Combine with 'hidden' flag test
  1061. } bdef
  1062.  
  1063. /drawwidget {            % <scalefactor> <annot> drawwidget -
  1064.   dup /AP knownoget {
  1065.     % Always use the Normal appearance.
  1066.     /N oget
  1067.         % Acrobat Distiller produces files in which this Form
  1068.         % XObject lacks Type and Subtype keys.  This is illegal,
  1069.         % but Acrobat Reader accepts it.  The only way we can
  1070.         % tell whether this is a Form or a set of sub-appearances
  1071.         % is by testing for the stream Length key.
  1072.     dup /Length known {
  1073.               % If this is a form then simply use it
  1074.       true
  1075.     } {
  1076.       1 index /AS knownoget not {
  1077.               % If we do not have AS then use any appearance
  1078.     { exch pop oforce exit } forall true
  1079.       } { 
  1080.         % Stack: annot Ndict AS
  1081.         % Get the specified appearance.  If no appearance, then
  1082.         % display nothing - set stack = false.
  1083.     knownoget
  1084.       } ifelse
  1085.     } ifelse
  1086.  
  1087.         % Stack: scale annot appearance true
  1088.         % Stack: scale annot false
  1089.     {
  1090.               % Draw appearance
  1091.       1 index annotrect pop pop translate
  1092.       2 index dup scale        % Apply scale factor
  1093.       DoForm
  1094.     } if
  1095.   } if pop pop
  1096. } bdef
  1097.  
  1098. %
  1099. %  For stamp object we have to determine the size of the output rectangle
  1100. %  and the size of the BBox for the stamp image.  From these we calculate
  1101. %  a scale factor for drawing the stamp.
  1102. %
  1103. /calcstampscale {        % <annot> calcstampscale scale
  1104.   dup annotrect 4 -2 roll pop pop pop    % get x width
  1105.   dup 0 lt { neg } if        % get magnitude
  1106.   exch /AP knownoget {
  1107.     /N knownoget {
  1108.       /BBox knownoget {
  1109.          aload pop 4 -2 roll pop pop pop
  1110.          div
  1111.       } {
  1112.         pop 1            % default to unity scaling
  1113.       } ifelse            % if we have /BBox
  1114.     } {
  1115.       pop 1
  1116.     } ifelse            % if we have /N
  1117.   } {
  1118.     pop 1
  1119.   } ifelse            % if we have /AP
  1120. } bdef
  1121.  
  1122. /drawlink {            % <annot> drawlink -
  1123.   dup drawborder
  1124.   1 exch drawwidget
  1125. } bdef
  1126.  
  1127. % Draw an annotation.
  1128. /drawannottypes mark
  1129.   /Link { drawlink } bind
  1130.   /Stamp { dup calcstampscale exch drawwidget } bind
  1131. .dicttomark readonly def
  1132. /drawannot {        % <annot> drawannot -
  1133.   dup annotvisible {
  1134.     gsave
  1135.     dup dup /Subtype get //drawannottypes exch .knownget {
  1136.       exec
  1137.     } {
  1138.       1 exch drawwidget        % Use drawwidget for everything else
  1139.     } ifelse            % type known
  1140.     grestore
  1141.   } if pop            % annotvisible
  1142. } bdef
  1143. currentdict /drawannottypes undef
  1144.  
  1145. end            % pdfdict
  1146. end            % GS_PDF_ProcSet
  1147. .setglobal
  1148.